<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>PF: Lists and Macros</title>
<link rev="made" href="mailto:www@openbsd.org">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="resource-type" content="document">
<meta name="description"   content="the OpenBSD FAQ page">
<meta name="keywords"      content="openbsd,faq,pf">
<meta name="distribution"  content="global">
</head>

<!--
Copyright (c) 2003, Nick Holland <nick@openbsd.org>
Copyright (c) 2003, 2004, Joel Knight <enabled@myrealbox.com>

Permission to use, copy, modify, and distribute this documentation for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.

THE DOCUMENTATION IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS DOCUMENTATION INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS DOCUMENTATION
-->

<body bgcolor="#ffffff" text="#000000">
<!-- Passes validator.w3.org, please keep it this way;
please, use a max of 72 chars per line -->

<a href="../../index.html">
<img alt="[OpenBSD]" height=30 width=141 src="../../images/smalltitle.gif" border="0">
</a>
<p>
[<a href="config.html">Previous: Getting Started</a>]
[<a href="index.html">Contents</a>]
[<a href="tables.html">Next: Tables</a>]

<h1><font color="#e00000">PF: Lists and Macros</font></h1>
<hr>

<h3>Table of Contents</h3>
<ul>
<li><a href="#lists">Lists</a>
<li><a href="#macros">Macros</a>
</ul>

<hr>

<a name="lists"></a>
<h2>Lists</h2>
A list allows the specification of multiple similar criteria within a
rule.  For example, multiple protocols, port numbers, addresses, etc.
So, instead of writing one filter rule for each IP address that needs to
be blocked, one rule can be written by specifying the IP addresses in a
list. Lists are defined by specifying items within <tt>{ }</tt>
brackets.

<p>
When
<a href="http://www.openbsd.org/cgi-bin/man.cgi?query=pfctl&amp;sektion=8&amp;manpath=OpenBSD+4.3"
>pfctl(8)</a> encounters a list during loading of the ruleset, it
creates multiple rules, one for each item in the list. For example:
<blockquote>
<tt>
block out on fxp0 from { 192.168.0.1, 10.5.32.6 } to any
</tt>
</blockquote>

<p>
gets expanded to:
<blockquote>
<tt>
block out on fxp0 from 192.168.0.1 to any<br>
block out on fxp0 from 10.5.32.6 to any
</tt>
</blockquote>

<p>
Multiple lists can be specified within a rule and are not limited to
just filter rules:
<blockquote>
<tt>
rdr on fxp0 proto tcp from any to any port { 22 80 } -&gt; \<br>
&nbsp;&nbsp;&nbsp;192.168.0.6<br>
block out on fxp0 proto { tcp udp } from { 192.168.0.1, \<br> 
&nbsp;&nbsp;&nbsp;10.5.32.6 } to any port { ssh telnet }
</tt>
</blockquote>

<p>
Note that the commas between list items are optional.

<p>
Lists can also contain nested lists:

<blockquote>
<tt>
trusted = "{ 192.168.1.2 192.168.5.36 }"<br>
pass in inet proto tcp from { 10.10.0.0/24 $trusted } to port 22
</tt>
</blockquote>

<p>
Beware of constructs like the following, dubbed "negated lists",
which are a common mistake:
<blockquote>
<tt>
pass in on fxp0 from { 10.0.0.0/8, !10.1.2.3 }
</tt>
</blockquote>

<p>
While the intended meaning is usually to match
"any address within 10.0.0.0/8, except for 10.1.2.3",
the rule expands to:
<blockquote>
<tt>
pass in on fxp0 from 10.0.0.0/8<br>
pass in on fxp0 from !10.1.2.3
</tt>
</blockquote>

<p>
which matches any possible address. Instead, a
<a href="tables.html">table</a> should be used.

<a name="macros"></a>
<h2>Macros</h2>
Macros are user-defined variables that can hold IP addresses, port
numbers, interface names, etc. Macros can reduce the complexity of a PF
ruleset and also make maintaining a ruleset much easier. 

<p>
Macro names must start with a letter and may contain letters, digits,
and underscores. Macro names cannot be reserved words such as <tt>pass</tt>, 
<tt>out</tt>, or <tt>queue</tt>.
<blockquote>
<tt>
ext_if = "fxp0"<br>
<br>
block in on $ext_if from any to any<br>
</tt>
</blockquote>

<p>
This creates a macro named <tt>ext_if</tt>. When a macro is referred to
after it's been created, its name is preceded with a <tt>$</tt> character.

<p>
Macros can also expand to lists, such as:
<blockquote>
<tt>
friends = "{ 192.168.1.1, 10.0.2.5, 192.168.43.53 }"
</tt>
</blockquote>

<p>
Macros can be defined recursively. Since macros are not expanded within
quotes the following syntax must be used:
<blockquote>
<tt>
host1      = "192.168.1.1"<br>
host2      = "192.168.1.2"<br>
all_hosts  = "{" $host1 $host2 "}"<br>
</tt>
</blockquote>

<p>
The macro <tt>$all_hosts</tt> now expands to 192.168.1.1, 192.168.1.2.

<p>
[<a href="config.html">Previous: Getting Started</a>]
[<a href="index.html">Contents</a>]
[<a href="tables.html">Next: Tables</a>]

<p>
<hr>
<a href="index.html"><img height="24" width="24" src="../../images/back.gif" border="0" alt="[back]"></a> 
<a href="mailto:www@openbsd.org">www@openbsd.org</a>
<br>
<small>$OpenBSD: macros.html,v 1.22 2008/07/27 17:13:47 nick Exp $</small>

</body>
</html> 
